/**   
 * Copyright © 2016 深圳市欧唯科技有限公司. All rights reserved.
 * 
 * @Title: PasswordUtil.java 
 * @Prject: Web
 * @Package: com.adv.util 
 * @Description: TODO
 * @author: WUQINGLONG   
 * @date: 2016年9月5日 上午11:06:47 
 * @version: V1.0   
 */
package com.adv.util;

import java.security.MessageDigest;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ClassName: PasswordUtil
 * @Description: TODO
 * @author: WUQINGLONG
 * @date: 2016年9月5日 上午11:06:47
 */
public class PasswordUtil {
	private static Logger logger = LoggerFactory.getLogger(PasswordUtil.class);

	/**
	 * 生成含有随机盐的密码
	 */
	public static String generate(String password) {
		Random r = new Random();
		StringBuilder sb = new StringBuilder(16);
		sb.append(r.nextInt(99999999)).append(r.nextInt(99999999));
		int len = sb.length();
		if (len < 16) {
			for (int i = 0; i < 16 - len; i++) {
				sb.append("0");
			}
		}
		String salt = sb.toString();
		password = md5Hex(password + salt);
		char[] cs = new char[48];
		for (int i = 0; i < 48; i += 3) {
			cs[i] = password.charAt(i / 3 * 2);
			cs[i + 1] = salt.charAt(i / 3);
			cs[i + 2] = password.charAt(i / 3 * 2 + 1);
		}
		return new String(cs);
	}

	/**
	 * 校验密码是否正确
	 */
	public static boolean verify(String password, String md5) {
		char[] cs1 = new char[32];
		char[] cs2 = new char[16];
		for (int i = 0; i < 48; i += 3) {
			cs1[i / 3 * 2] = md5.charAt(i);
			cs1[i / 3 * 2 + 1] = md5.charAt(i + 2);
			cs2[i / 3] = md5.charAt(i + 1);
		}
		String salt = new String(cs2);
		return md5Hex(password + salt).equals(new String(cs1));
	}

	/**
	 * 获取十六进制字符串形式的MD5摘要
	 */
	public static String md5Hex(String src) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] bs = md5.digest(src.getBytes());
			return new String(bytes2chars(bs));
		} catch (Exception e) {
			logger.error("src=" + src);
			logger.error(e.getMessage());
		}
		return null;
	}

	private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
			'f' };

	private static char[] bytes2chars(byte[] bytes) {
		final int nBytes = bytes.length;
		char[] result = new char[nBytes << 1];
		int j = 0;
		for (int i = 0; i < nBytes; i++) {
			result[j++] = HEX[(0xF0 & bytes[i]) >>> 4];
			result[j++] = HEX[(0x0F & bytes[i])];
		}
		return result;
	}

	// private static byte[] char2bytes(CharSequence s) {
	// int nChars = s.length();
	// if (nChars % 2 != 0) {
	// throw new IllegalArgumentException("Hex-encoded string must have an even
	// number of characters");
	// }
	// byte[] result = new byte[nChars / 2];
	// for (int i = 0; i < nChars; i += 2) {
	// int msb = Character.digit(s.charAt(i), 16);
	// int lsb = Character.digit(s.charAt(i + 1), 16);
	// if (msb < 0 || lsb < 0) {
	// throw new IllegalArgumentException("Non-hex character in input: " + s);
	// }
	// result[i / 2] = (byte) ((msb << 4) | lsb);
	// }
	// return result;
	// }

	public static void main(String[] args) {
		String name = "1q2w3e4r5t@";
		String password = generate(name);
		System.out.println(name + " --> " + password);
		System.out.println("verfity result is " + verify(name, password));
	}
}
